package com.ycxh.module.FileStore.util;

import com.ycxh.module.FileStore.entity.FileInfo;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 文件操作的工具类
 */
public class FileUtils {

    /**
     * 获取文件/文件夹的最后修改的时间
     *
     * @param time
     * @return
     */
    public static String getUpdateTime(long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//时间格式化
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(time);
        return sdf.format(cal.getTime());
    }

    /**
     * 获取文件/文件夹的最后修改的时间
     *
     * @param time
     * @return
     */
    public static Date getUpdateDate(long time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//时间格式化
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(time);
        return cal.getTime();
    }

    /**
     * 获取文件/目录大小
     *
     * @return
     */
    public static double getFileSize(File file) {
        if (file.isFile()) {//是文件
            return file.length() / 1000.0;
        }
        return 0;
    }

    /**
     * 根据文件后缀名判断文件类型
     *
     * @return
     */
    public static String getFileType(String fileName) {
        int index = fileName.lastIndexOf(".");
        String type = fileName.substring(index, fileName.length());//获取文件后缀名
        switch (type) {
            case ".txt":
                return "文本文档";
            case ".docx":
            case ".doc":
                return "Word文档";
            case ".exe":
                return "应用程序";
            case ".lnk":
                return "快捷方式";
            case ".zip":
                return "压缩文件";
            default:
                return type.substring(1, type.length()).toUpperCase() + "文件";
        }
    }

    /**
     * 递归获取指定路径下的所有文件，文件夹，并返回
     */
    public static List<FileInfo> getFiles(String path) {
        File file = new File(path);
        List<FileInfo> filesList = new ArrayList<FileInfo>();
        // 如果这个路径是文件夹
        if (file.isDirectory()) {
            // 获取路径下的所有文件
            File[] files = file.listFiles();
            if (files != null && files.length > 0) {//包含文件或者文件夹
                for (int i = 0; i < files.length; i++) {
                    FileInfo f = new FileInfo(files[i].getName(),
                            getUpdateTime(files[i].lastModified()),
                            getUpdateDate(files[i].lastModified()),
                            "待定",
                            String.valueOf(getFileSize(files[i])) + " KB",
                            files[i].length(),
                            files[i].getPath());
                    if (files[i].isDirectory()) {//是文件夹
                        f.setType("文件夹");
                        f.setSize("");
                        filesList.add(f);
                    } else {
                        f.setType(f.getFileName().contains(".") ? getFileType(f.getFileName()) : "不合法文件");
                        filesList.add(f);
                    }
                }
            }
        } else {
            FileInfo f2 = new FileInfo(file.getName(),
                    getUpdateTime(file.lastModified()),
                    getUpdateDate(file.lastModified()),
                    "文件",
                    String.valueOf(getFileSize(file)), file.getPath());
            filesList.add(f2);
        }
        return filesList;
    }

    /**
     * 删除指定目录下的所有文件
     */
    public static boolean deleteFile(String path, String ROOT_PATH) {
        File file = new File(path);
        boolean result = false;//返回删除的结果
        if (file.exists()) {
            //delete()方法不能删除非空文件夹，所以得用递归方式将file下所有包含内容删除掉，然后再删除file
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File f : files) {
                    deleteFile(f.getPath(), ROOT_PATH);//递归实现 ：删除包含文件的文件夹
                }
            }
            result = file.delete();
        }
        if (StringUtils.isNotBlank(ROOT_PATH) && path.equals(ROOT_PATH)) {//如果删除的是根目录，就恢复根目录文件夹
            new File(ROOT_PATH).mkdir();
        }
        return result;
    }

    /**
     * 创建文件夹/文件
     */
    public static boolean addFileOrDir(String newDirPath, String type) {
        boolean ok = false;
        File file = new File(newDirPath);
        if (type.equals("dir")) {//创建文件夹
            ok = file.mkdir();
        } else {//创建新文件
            try {
                ok = file.createNewFile();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                ok = false;
            }
        }
        return ok;
    }

    /**
     * 文件重命名
     *
     * @param path
     * @param newName
     * @return
     */
    public static boolean reName(String path, String newName) {
        File old = new File(path);
        File new1 = new File(path.substring(0, path.lastIndexOf("\\") + 1) + newName);
        boolean r = old.renameTo(new1);
        if (r) {
            return true;
        }
        return false;//文件重名
    }

    /**
     * 文件移动  ok
     */
    public static boolean moveFile(String src, String dest) {//文件移动（重命路径）
        File file = new File(src);
        if (file.exists()) {
            File newfile = new File(dest);
            if (file.renameTo(newfile)) {
                System.out.println("移动文件成功！");
                return true;
            } else {
                System.out.println("移动失败！新文件名已存在");
                return false;
            }
        } else {
            System.out.println("目标文件不存在！");
            return false;
        }
    }

    /**
     * 文件复制
     *
     * @param src
     * @param dst
     */
    public static boolean copyFile(String src, String dst) {
        File srcFile = new File(src);
        File dstDir = new File(dst);
        if (!srcFile.exists() || srcFile.isDirectory()) {
            return false;
        }
        if (!dstDir.exists()) {
            dstDir.mkdirs();
        }
        String oldFileName = srcFile.getName();
        Pattern suffixPattern = Pattern.compile("\\.\\w+");
        Matcher matcher = suffixPattern.matcher(oldFileName);
        String nameBody;
        String suffix;
        if (matcher.find()) {
            nameBody = oldFileName.substring(0, matcher.start());
            suffix = oldFileName.substring(matcher.start());
        } else {
            nameBody = oldFileName;
            suffix = "";
        }
        int fileNumber = 0;
        File newFile = new File(dstDir, oldFileName);
        while (newFile.exists()) {
            fileNumber++;
            String newFileName = nameBody + "-copy" + fileNumber + suffix;
            newFile = new File(dstDir, newFileName);
        }
        FileInputStream fileInputStream;
        FileOutputStream fileOutputStream;
        try {
            fileInputStream = new FileInputStream(srcFile);
            FileChannel fileIn = fileInputStream.getChannel();//通道
            fileOutputStream = new FileOutputStream(newFile);
            FileChannel fileOut = fileOutputStream.getChannel();
            fileIn.transferTo(0, fileIn.size(), fileOut);
            fileIn.close();
            fileOut.close();
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    /**
     * 复制文件或文件夹
     * 如果目标文件夹不存在则自动创建
     * 如果文件或文件夹已经存在则自动编号-copy n
     *
     * @param src    源文件或文件夹绝对路径
     * @param dstDir 目标文件夹绝对路径
     * @return 是否成功复制文件或文件夹
     */
    public static boolean copy(String srcFile, String dst) {
        File src = new File(srcFile);
        File dstDir = new File(dst);
        if (!src.exists()) {
            return false;
        }
        if (!dstDir.exists()) {
            dstDir.mkdirs();
        }
        if (src.isFile()) {// 文件
            copyFile(srcFile, dst);
        } else {// 文件夹
            String oldSrcName = src.getName();
            int srcNumber = 0;
            File newSrcDir = new File(dstDir, oldSrcName);
            while (newSrcDir.exists()) {
                srcNumber++;
                String newSrcName = oldSrcName + "-copy" + srcNumber;
                newSrcDir = new File(dstDir, newSrcName);
            }
            newSrcDir.mkdirs();
            for (File srcSub : src.listFiles()) {
                copy(srcSub.toString(), newSrcDir.toString());// 递归复制源文件夹下子文件和文件夹
            }
        }
        return true;
    }

    /**
     * 文件搜索
     */
    public static List<FileInfo> searchFiles(File file, String search) {
        List<FileInfo> searchResult = new ArrayList<>();
        if (file != null && file.exists()) {
            File[] f = file.listFiles();
            if (f != null) {
                if (file.isDirectory() && file.getName().contains(search)) {
                    //获取文件属性
                    FileInfo f1 = new FileInfo(file.getName(),
                            FileUtils.getUpdateTime(file.lastModified()),
                            FileUtils.getUpdateDate(file.lastModified()),
                            "文件夹", " ", file.getPath());
                    searchResult.add(f1);
                }
                for (int i = 0; i < f.length; i++) {
                    searchFiles(f[i], search);
                }
            } else {
                if (file.getName().contains(search)) {//满足查询条件
                    FileInfo f2 = null;
                    if (file.isDirectory()) {
                        //获取文件属性
                        f2 = new FileInfo(file.getName(),
                                FileUtils.getUpdateTime(file.lastModified()),
                                FileUtils.getUpdateDate(file.lastModified()),
                                "文件夹", " ", file.getPath());
                    } else {
                        String fileName = file.getName();
                        String fileType = fileName.contains(".") & fileName.lastIndexOf(".") > 0 & fileName.lastIndexOf(".") < fileName.length() ? fileName.substring(fileName.lastIndexOf(".") + 1) : "non";
                        if (!fileType.equals("non")) {//正常文件类型
                            //获取文件属性
                            f2 = new FileInfo(file.getName(),
                                    FileUtils.getUpdateTime(file.lastModified()),
                                    FileUtils.getUpdateDate(file.lastModified()),
                                    fileType.toUpperCase() + "文件", String.valueOf(FileUtils.getFileSize(file)) + " KB", file.getPath());
                        } else {
                            //获取文件属性
                            f2 = new FileInfo(file.getName(),
                                    FileUtils.getUpdateTime(file.lastModified()),
                                    FileUtils.getUpdateDate(file.lastModified()),
                                    "不合法文件", String.valueOf(FileUtils.getFileSize(file)) + " KB", file.getPath());
                        }

                    }
                    searchResult.add(f2);
                }
            }
        }
        return searchResult;
    }

}
